from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Form
from sqlalchemy.orm import Session
from database import get_db
from models import User, Work
from schemas import ResponseModel, FileUploadResponse, WorkCreate
from auth import get_current_active_user
from utils import process_image_upload, validate_file_type, validate_file_size, save_upload_file, generate_filename, get_file_url
from config import settings
import os
import aiofiles
from typing import Optional

router = APIRouter(prefix="/api/upload", tags=["文件上传"])

@router.post("/avatar", response_model=ResponseModel)
async def upload_avatar(
    avatar: UploadFile = File(..., description="头像文件"),
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    上传用户头像
    
    Args:
        avatar: 头像文件
        current_user: 当前登录用户
        db: 数据库会话
    
    Returns:
        ResponseModel: 包含头像URL的响应
    
    Raises:
        HTTPException: 如果文件验证失败
    """
    # 验证文件类型
    if not validate_file_type(avatar, settings.allowed_image_types):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="不支持的图片格式，请上传 JPG、PNG 或 GIF 格式的图片"
        )
    
    # 验证文件大小（头像限制为2MB）
    max_avatar_size = 2 * 1024 * 1024  # 2MB
    if not validate_file_size(avatar, max_avatar_size):
        raise HTTPException(
            status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
            detail="头像文件大小不能超过2MB"
        )
    
    try:
        # 处理图片上传
        upload_result = await process_image_upload(avatar, "avatar")
        
        # 更新用户头像
        current_user.avatar = upload_result["url"]
        db.commit()
        
        return ResponseModel(
            code=200,
            message="头像上传成功",
            data={
                "url": upload_result["url"]
            }
        )
    
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"头像上传失败: {str(e)}"
        )

@router.post("/work", response_model=ResponseModel)
async def upload_work_file(
    file: UploadFile = File(..., description="作品文件"),
    type: str = Form(..., description="文件类型: image/video/audio/document"),
    current_user: User = Depends(get_current_active_user)
):
    """
    上传作品文件
    
    Args:
        file: 作品文件
        type: 文件类型
        current_user: 当前登录用户
    
    Returns:
        ResponseModel: 包含文件信息的响应
    
    Raises:
        HTTPException: 如果文件验证失败
    """
    # 根据类型验证文件
    if type == "image":
        if not validate_file_type(file, settings.allowed_image_types):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="不支持的图片格式"
            )
        try:
            upload_result = await process_image_upload(file, "work")
            return ResponseModel(
                code=200,
                message="图片上传成功",
                data=upload_result
            )
        except Exception as e:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"图片上传失败: {str(e)}"
            )
    
    elif type == "video":
        if not validate_file_type(file, settings.allowed_video_types):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="不支持的视频格式"
            )
        
        # 验证文件大小（视频文件限制更大，比如100MB）
        max_video_size = 100 * 1024 * 1024  # 100MB
        if not validate_file_size(file, max_video_size):
            raise HTTPException(
                status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
                detail="视频文件大小不能超过100MB"
            )
        
        try:
            # 生成文件名
            filename = generate_filename(file.filename, "video")
            save_dir = os.path.join(settings.upload_dir, "works")
            
            # 保存文件
            file_path = await save_upload_file(file, save_dir, filename)
            file_size = os.path.getsize(file_path)
            file_url = get_file_url(file_path)
            
            return ResponseModel(
                code=200,
                message="视频上传成功",
                data={
                    "url": file_url,
                    "thumbnail": None,  # 视频缩略图需要额外处理
                    "size": file_size,
                    "mime_type": file.content_type,
                    "filename": filename
                }
            )
        
        except Exception as e:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"视频上传失败: {str(e)}"
            )
    
    elif type == "audio":
        if not validate_file_type(file, settings.allowed_audio_types):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="不支持的音频格式"
            )
        
        # 验证文件大小（音频文件限制为50MB）
        max_audio_size = 50 * 1024 * 1024  # 50MB
        if not validate_file_size(file, max_audio_size):
            raise HTTPException(
                status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
                detail="音频文件大小不能超过50MB"
            )
        
        try:
            # 生成文件名
            filename = generate_filename(file.filename, "audio")
            save_dir = os.path.join(settings.upload_dir, "works")
            
            # 保存文件
            file_path = await save_upload_file(file, save_dir, filename)
            file_size = os.path.getsize(file_path)
            file_url = get_file_url(file_path)
            
            return ResponseModel(
                code=200,
                message="音频上传成功",
                data={
                    "url": file_url,
                    "thumbnail": None,
                    "size": file_size,
                    "mime_type": file.content_type,
                    "filename": filename
                }
            )
        
        except Exception as e:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"音频上传失败: {str(e)}"
            )
    
    else:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="不支持的文件类型"
        )

@router.post("/work-complete", response_model=ResponseModel)
async def upload_complete_work(
    title: str = Form(..., description="作品标题"),
    description: Optional[str] = Form(None, description="作品描述"),
    category: str = Form(..., description="作品分类"),
    tags: Optional[str] = Form(None, description="标签，逗号分隔"),
    file: UploadFile = File(..., description="作品文件"),
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db)
):
    """
    上传完整作品（文件+信息）
    
    Args:
        title: 作品标题
        description: 作品描述
        category: 作品分类
        tags: 标签字符串
        file: 作品文件
        current_user: 当前登录用户
        db: 数据库会话
    
    Returns:
        ResponseModel: 包含作品信息的响应
    
    Raises:
        HTTPException: 如果验证失败
    """
    # 验证分类
    valid_categories = ["image", "video", "music", "text"]
    if category not in valid_categories:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"无效的作品分类，支持的分类: {', '.join(valid_categories)}"
        )
    
    # 处理标签
    tag_list = []
    if tags:
        tag_list = [tag.strip() for tag in tags.split(",") if tag.strip()]
    
    try:
        # 根据分类上传文件
        if category == "image":
            upload_result = await process_image_upload(file, "work")
        else:
            # 其他类型文件的简单上传
            filename = generate_filename(file.filename, category)
            save_dir = os.path.join(settings.upload_dir, "works")
            file_path = await save_upload_file(file, save_dir, filename)
            
            upload_result = {
                "url": get_file_url(file_path),
                "thumbnail": None,
                "size": os.path.getsize(file_path),
                "mime_type": file.content_type,
                "filename": filename
            }
        
        # 创建作品记录
        db_work = Work(
            title=title,
            description=description,
            category=category,
            tags=tag_list,
            file_url=upload_result["url"],
            thumbnail=upload_result.get("thumbnail"),
            file_size=upload_result.get("size"),
            mime_type=upload_result.get("mime_type"),
            user_id=current_user.id
        )
        
        db.add(db_work)
        db.commit()
        db.refresh(db_work)
        
        return ResponseModel(
            code=200,
            message="作品上传成功",
            data={
                "id": db_work.id,
                "title": db_work.title,
                "description": db_work.description,
                "category": db_work.category,
                "tags": db_work.tags or [],
                "thumbnail": db_work.thumbnail,
                "fileUrl": db_work.file_url,
                "views": db_work.views,
                "likes": db_work.likes,
                "comments": db_work.comments,
                "createdAt": db_work.created_at.isoformat()
            }
        )
    
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"作品上传失败: {str(e)}"
        )

@router.get("/limits", response_model=ResponseModel)
async def get_upload_limits():
    """
    获取文件上传限制信息
    
    Returns:
        ResponseModel: 包含上传限制的响应
    """
    return ResponseModel(
        code=200,
        message="success",
        data={
            "maxFileSize": settings.max_file_size,
            "allowedImageTypes": settings.allowed_image_types.split(","),
            "allowedVideoTypes": settings.allowed_video_types.split(","),
            "allowedAudioTypes": settings.allowed_audio_types.split(","),
            "maxAvatarSize": 2 * 1024 * 1024,  # 2MB
            "maxVideoSize": 100 * 1024 * 1024,  # 100MB
            "maxAudioSize": 50 * 1024 * 1024   # 50MB
        }
    )